package com.imis.module.system.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.annotation.HashCacheEvict;
import com.imis.base.constant.CacheConstant;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.DataBaseConstant;
import com.imis.base.util.ConvertUtils;
import com.imis.module.base.impl.BaseServiceImpl;
import com.imis.module.system.dao.SysOrganizationMapper;
import com.imis.module.system.model.converter.SysOrganizationConverter;
import com.imis.module.system.model.po.SysOrganization;
import com.imis.module.system.model.po.SysUserOrganization;
import com.imis.module.system.model.ro.PagingQueryOrganizationDTO;
import com.imis.module.system.model.ro.SysGrantOrganizationToUserRO;
import com.imis.module.system.model.vo.DropDownBoxTreeVO;
import com.imis.module.system.model.vo.SysOrganizationTreeVO;
import com.imis.module.system.model.vo.SysOrganizationVO;
import com.imis.module.system.model.vo.SysUserOrganizationVO;
import com.imis.module.system.service.ISysOrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 组织机构 服务实现类
 * </p>
 *
 * @author XinLau
 * @since 2020-04-22
 */
@Slf4j
@Service
@DS(DataBaseConstant.DATA_SOURCE_MASTER)
public class SysOrganizationServiceImpl extends BaseServiceImpl<SysOrganizationMapper, SysOrganization> implements ISysOrganizationService {

    /**
     * 生成组织机构Tree
     *
     * @param sysOrganizationParentList - 组织机构对象集合
     * @return List<SysMenuTreeVO> - 组织机构Tree
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    private List<SysOrganizationTreeVO> querySysOrganizationTreeForPagingQuery(List<SysOrganizationTreeVO> sysOrganizationParentList) {
        // 此处这样操作完全是因为分页查询只分页查询一级菜单
        List<SysOrganizationTreeVO> sysOrganizationTreeVOList = new ArrayList<>();
        // 1.查询所有非一级组织机构
        List<SysOrganization> sysOrganizationList = mapper.selectList(Wrappers.<SysOrganization>lambdaQuery().ne(SysOrganization::getParentId, 0L).orderByDesc(SysOrganization::getSortOrder));
        if (!sysOrganizationParentList.isEmpty()) {
            for (SysOrganizationTreeVO sysOrganizationParen : sysOrganizationParentList) {
                sysOrganizationTreeVOList.add(findChildOrganization(sysOrganizationParen, SysOrganizationConverter.INSTANCE.getTreeReturnValue(sysOrganizationList)));
            }
        }
        return sysOrganizationTreeVOList;
    }

    /**
     * 生成组织机构Tree
     *
     * @param sysOrganizationTreeVOList - 组织机构对象集合
     * @return List<SysOrganizationTreeVO> - 组织机构Tree
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    private List<SysOrganizationTreeVO> querySysOrganizationTree(List<SysOrganizationTreeVO> sysOrganizationTreeVOList) {
        List<SysOrganizationTreeVO> organizationTreeArrayList = new ArrayList<>();
        if (!sysOrganizationTreeVOList.isEmpty()) {
            for (SysOrganizationTreeVO sysOrganizationParen : sysOrganizationTreeVOList) {
                if ("0".equals(sysOrganizationParen.getParentId()) || ConvertUtils.isEmpty(sysOrganizationParen.getParentId())) {
                    organizationTreeArrayList.add(findChildOrganization(sysOrganizationParen, sysOrganizationTreeVOList));
                }
            }
        }
        return organizationTreeArrayList;
    }

    /**
     * 递归查找子节点
     *
     * @param sysOrganizationParen      - 父对象
     * @param sysOrganizationTreeVOList - 集合对象
     * @return SysMenuTreeVO -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/23 15:37
     */
    private SysOrganizationTreeVO findChildOrganization(SysOrganizationTreeVO sysOrganizationParen, List<SysOrganizationTreeVO> sysOrganizationTreeVOList) {
        for (SysOrganizationTreeVO sysOrganization : sysOrganizationTreeVOList) {
            // 1.判断父对象的编号是不是等于子对象的父编号
            if (sysOrganizationParen.getId().equals(sysOrganization.getParentId())) {
                //  2_1.判断父对象内的字段项为空时的操作
                if (sysOrganizationParen.getChildOrganization() == null) {
                    sysOrganizationParen.setChildOrganization(new ArrayList<>());
                }
                //  2_2.递归查找子节点
                sysOrganizationParen.getChildOrganization().add(findChildOrganization(sysOrganization, sysOrganizationTreeVOList));
            }
        }
        return sysOrganizationParen;
    }

    /**
     * 生成下拉树
     *
     * @param dropDownBoxTreeVOList - 集合对象
     * @return List<DropDownBoxTreeVO> -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/23 15:37
     */
    private List<DropDownBoxTreeVO> generateDropDownBoxTree(List<DropDownBoxTreeVO> dropDownBoxTreeVOList) {
        List<DropDownBoxTreeVO> downBoxTreeVOList = new ArrayList<>();
        for (DropDownBoxTreeVO downBoxTreeVO : dropDownBoxTreeVOList) {
            boolean addTheNode = Boolean.TRUE;
            for (DropDownBoxTreeVO downBoxTree : dropDownBoxTreeVOList) {
                if (downBoxTreeVO.getParentId() != null && downBoxTreeVO.getParentId().equals(downBoxTree.getKey())) {
                    addTheNode = false;
                    if (downBoxTree.getChildren() == null) {
                        downBoxTree.setChildren(new ArrayList<>());
                    }
                    downBoxTree.getChildren().add(downBoxTreeVO);
                }
            }
            if (addTheNode) {
                downBoxTreeVOList.add(downBoxTreeVO);
            }
        }
        return downBoxTreeVOList;
    }

    /**
     * 分页查询组织机构
     *
     * @param pagingQueryOrganizationDTO - 组织机构查询对象
     * @return List<SysOrganizationTreeVO> - 分页组织机构
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    @Override
    public Page<SysOrganizationTreeVO> pagingQuerySysOrganizationParentListByParameter(final PagingQueryOrganizationDTO pagingQueryOrganizationDTO) {
        // 1.页码、页长
        Page<SysOrganization> sysOrganizationPage = new Page<>(pagingQueryOrganizationDTO.getPageNumber(), pagingQueryOrganizationDTO.getPageSize());
        // 2.排序字段
        sysOrganizationPage.addOrder(OrderItem.asc("sort_order"), OrderItem.desc(DataBaseConstant.CREATE_TIME_FIELD), OrderItem.desc(DataBaseConstant.UPDATE_TIME_FIELD));
        // 3.条件分页查询
        sysOrganizationPage = mapper.pagingQuerySysOrganizationParentListByParameter(sysOrganizationPage, pagingQueryOrganizationDTO);
        // 4.PO分页对象转VO实体分页对象
        Page<SysOrganizationTreeVO> sysOrganizationTreePage = SysOrganizationConverter.INSTANCE.getTreeReturnValue(sysOrganizationPage);
        // 5.配置生成组织机构Tree
        sysOrganizationTreePage.setRecords(querySysOrganizationTreeForPagingQuery(sysOrganizationTreePage.getRecords()));
        // 6.返回值
        return sysOrganizationTreePage;
    }

    /**
     * 根据组织机构名查询组织机构
     *
     * @param organizationName - 组织机构名称
     * @return SysMenu - 组织机构
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    @Override
    public SysOrganization queryOrganizationByName(final String organizationName) {
        return mapper.selectOne(Wrappers.<SysOrganization>lambdaQuery().eq(SysOrganization::getOrganizationName, organizationName));
    }

    /**
     * 根据组织机构标识查询用户编号
     *
     * @param organizationIdentification - 组织机构标识
     * @return Long[] 用户编号
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public Long[] queryUserIdentificationByOrganizationIdentification(final Long organizationIdentification) {
        return mapper.queryUserIdentificationByOrganizationIdentification(organizationIdentification).toArray(new Long[0]);
    }

    /**
     * 根据父级组织机构编号查询子级组织机构
     *
     * @param parentId - 父级组织机构标识
     * @return List<SysMenuVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public List<SysOrganizationVO> selectSysOrganizationListByParentId(final Long parentId) {
        List<SysOrganization> sysOrganizationList = mapper.selectList(Wrappers.<SysOrganization>lambdaQuery().eq(SysOrganization::getParentId, parentId).orderByDesc(SysOrganization::getSortOrder));
        return SysOrganizationConverter.INSTANCE.getReturnValue(sysOrganizationList);
    }

    /**
     * 根据组织机构编号逻辑删除组织机构
     *
     * @param organizationIdentification - 父级组织机构标识
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public Boolean deleteOrganizationById(final Long organizationIdentification) {
        // 影响行数
        int change = mapper.changeOrganizationDelFlagByIdentification(CommonConstant.DEL_FLAG_DELETE, organizationIdentification);
        return change > 0;
    }

    /**
     * 根据组织机构编号修改组织机构信息
     *
     * @param sysOrganization - 组织机构修改对象
     * @return Boolean
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/16 09:30
     */
    @Override
    public Boolean updateByOrganizationIdentification(final SysOrganization sysOrganization) {
        int update = mapper.updateByOrganizationIdentification(sysOrganization);
        return update > 0;
    }

    /**
     * 获取组织机构集合
     *
     * @return List<SysOrganization> - 组织机构集合
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/25 9:44
     */
    @Override
    public List<SysOrganization> querySysOrganizationList() {
        return mapper.selectList(Wrappers.<SysOrganization>lambdaQuery().orderByDesc(SysOrganization::getParentId).orderByDesc(SysOrganization::getSortOrder));
    }

    /**
     * 查询组织机构树
     *
     * @return List<SysOrganizationTreeVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    @Override
    public List<SysOrganizationTreeVO> querySysOrganizationTreeList() {
        // 生成组织机构Tree
        return querySysOrganizationTree(SysOrganizationConverter.INSTANCE.getTreeReturnValue(querySysOrganizationList()));
    }

    /**
     * 根据父组织机构查询组织机构树
     *
     * @param parentSysOrganization - 父组织机构
     * @return List<SysOrganizationTreeVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/17 14:54
     */
    @Override
    public List<SysOrganizationTreeVO> queryOrganizationTreeByParent(final SysOrganization parentSysOrganization) {
        List<SysOrganizationTreeVO> sysMenuTreeVOList = new ArrayList<>();
        SysOrganizationTreeVO parentSysOrganizationTreeVO = SysOrganizationConverter.INSTANCE.getTreeReturnValue(parentSysOrganization);
        // 查询所有组织机构信息
        List<SysOrganization> sysOrganizationList = mapper.selectList(Wrappers.<SysOrganization>lambdaQuery().orderByDesc(SysOrganization::getParentId).orderByDesc(SysOrganization::getSortOrder));
        if (!sysOrganizationList.isEmpty()) {
            // 确定子父关系
            sysMenuTreeVOList.add(findChildOrganization(parentSysOrganizationTreeVO, SysOrganizationConverter.INSTANCE.getTreeReturnValue(sysOrganizationList)));
        } else {
            sysMenuTreeVOList.add(parentSysOrganizationTreeVO);
        }
        return sysMenuTreeVOList;
    }

    /**
     * 根据用户ID查询用户拥有的组织机构
     *
     * @param userId - 用户ID
     * @return List<SysUserOrganizationVO>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/5/6 14:54
     */
    @Override
    public List<SysUserOrganizationVO> queryOrganizationByUserIdentification(final Long userId) {
        // 查询用户拥有的组织机构
        return mapper.queryOrganizationByUserIdentification(userId);
    }

    /**
     * 用户授权组织机构
     *
     * @param sysGrantOrganizationToUser - 用户授权组织机构
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/19 11:10
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean grantOrganizationToUser(final SysGrantOrganizationToUserRO sysGrantOrganizationToUser) {
        try {
            // 1.清除之前的授权
            Long userId = sysGrantOrganizationToUser.getUserId();
            // 影响的的行数
            int delete = mapper.deleteGrantByUserId(userId);
            if (delete >= 0) {
                // 对象转换
                List<SysUserOrganization> sysUserOrganizationList = SysOrganizationConverter.INSTANCE.grantOrganizationToUser(sysGrantOrganizationToUser);
                // 2.授权处理
                int grant = mapper.grantOrganizationToUser(sysUserOrganizationList);
                return grant > 0;
            }
            return Boolean.FALSE;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Boolean.FALSE;
        }
    }

    /**
     * 撤销用户组织机构授权
     *
     * @param userId - 用户编号
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/20 14:22
     */
    @Override
    @HashCacheEvict(hashIdentification = CacheConstant.PREFIX_SYS_USER_ORGANIZATION, hashKey = "'USER_ID_' + #userId")
    public Boolean terminateAllOrganizationToUser(final Long userId) {
        try {
            // 影响的的行数
            int delete = mapper.deleteGrantByUserId(userId);
            return delete > 0;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Boolean.FALSE;
        }
    }

    /**
     * 根据组织机构名称获取下拉
     *
     * @param organizationName - 组织机构名称
     * @return Result
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/3/30 12:01
     */
    @Override
    public List<DropDownBoxTreeVO> queryOrganizationTreeByOrganizationName(final String organizationName) {
        // 查询组织机构
        List<SysOrganization> sysOrganizationList = mapper.queryOrganizationTreeByOrganizationName(organizationName);
        // 组织机构转成下拉对象
        List<DropDownBoxTreeVO> dropDownBoxTreeVOList = SysOrganizationConverter.INSTANCE.getDropDownBoxTreeReturnValue(sysOrganizationList);
        // 生成下拉树
        return generateDropDownBoxTree(dropDownBoxTreeVOList);
    }

}